#pragma once

#pragma warning( disable: 4275 4251 )

#include "zacarray.h"
#include "zgepnt3d.h"

#include "zdbmain.h"
#include "zdbents.h"

#pragma pack (push, 8)

class UcDbImpDataCell;
class UcDbImpDataColumn;

class UcDbDataCell : public UcRxObject
{
public:
    enum CellType {
        kUnknown = 0,
        kInteger,
        kDouble,
        kCharPtr,
        kPoint,
        kObjectId,
        kHardOwnerId,
        kSoftOwnerId,
        kHardPtrId,
        kSoftPtrId,
        kBool,
        kVector
    };

    UcDbDataCell();
    UcDbDataCell(const UcDbDataCell& rCell);

    UcDbDataCell(bool b);
    UcDbDataCell(int i);
    UcDbDataCell(double d);
    UcDbDataCell(const ZTCHAR * pChar);
    UcDbDataCell(const UcGePoint3d& point);
    UcDbDataCell(const UcGeVector3d& vec);
    UcDbDataCell(const UcDbObjectId& id);
    UcDbDataCell(const UcDbHardOwnershipId& hoId);
    UcDbDataCell(const UcDbSoftOwnershipId& soId);
    UcDbDataCell(const UcDbHardPointerId&   hpId);
    UcDbDataCell(const UcDbSoftPointerId&   spId);

    virtual ~UcDbDataCell();
    UCRX_DECLARE_MEMBERS(UcDbDataCell);

    virtual void init();

    virtual UcDbDataCell& operator = (const UcDbDataCell &cell);
    virtual UcDbDataCell& operator = (bool b);
    virtual UcDbDataCell& operator = (int i);
    virtual UcDbDataCell& operator = (double d);
    virtual UcDbDataCell& operator = (const ZTCHAR * pChar);
    virtual UcDbDataCell& operator = (const UcGePoint3d &pt);
    virtual UcDbDataCell& operator = (const UcGeVector3d &vec);
    virtual UcDbDataCell& operator = (const UcDbObjectId &id);
    virtual UcDbDataCell& operator = (const UcDbHardOwnershipId &hoId);
    virtual UcDbDataCell& operator = (const UcDbSoftOwnershipId &soId);
    virtual UcDbDataCell& operator = (const UcDbHardPointerId   &hpId);
    virtual UcDbDataCell& operator = (const UcDbSoftPointerId   &spId);

    virtual operator bool() const;
    virtual operator int() const;
    virtual operator double() const;
    virtual operator const ZTCHAR *() const;
    virtual operator UcGePoint3d&()const;
    virtual operator UcGeVector3d&()const;
    virtual operator UcDbObjectId&() const;
    virtual operator UcDbHardOwnershipId&() const;
    virtual operator UcDbSoftOwnershipId&() const;
    virtual operator UcDbHardPointerId&() const;
    virtual operator UcDbSoftPointerId&() const;

    virtual bool operator == (const UcDbDataCell &cell) const;
    virtual bool operator != (const UcDbDataCell &cell) const;

    virtual UcDbDataCell::CellType type() const;

private:
    friend class UcDbSystemInternals;

    UcDbImpDataCell* mpImpDataCell;
};

typedef UcArray<UcDbDataCell, UcArrayObjectCopyReallocator<UcDbDataCell> >
    UcDbDataCellArray;

class UcDbDataColumn : public UcRxObject
{
public:
    UcDbDataColumn();
    UcDbDataColumn(const UcDbDataColumn& rCol);
    UcDbDataColumn(const UcDbDataCell::CellType type,
        const ZTCHAR * pColName = NULL);

    virtual ~UcDbDataColumn();
    UCRX_DECLARE_MEMBERS(UcDbDataColumn);

    virtual ZSoft::UInt32 physicalLength() const;
    virtual ZSoft::UInt32 growLength() const;
    virtual Ucad::ErrorStatus setPhysicalLength(ZSoft::UInt32 n);
    virtual Ucad::ErrorStatus setGrowLength(ZSoft::UInt32 n);

    virtual UcDbDataColumn& operator = (const UcDbDataColumn& col);

    virtual Ucad::ErrorStatus setColumnType(UcDbDataCell::CellType type);
    virtual UcDbDataCell::CellType columnType() const;
    virtual Ucad::ErrorStatus setColumnName(const ZTCHAR * pName);
    virtual const ZTCHAR * columnName() const;

    virtual Ucad::ErrorStatus getCellAt(ZSoft::UInt32 index, UcDbDataCell& outCell) const;
    virtual Ucad::ErrorStatus setCellAt(ZSoft::UInt32 index, const UcDbDataCell& cell);
    virtual Ucad::ErrorStatus appendCell(const UcDbDataCell& cell);
    virtual Ucad::ErrorStatus insertCellAt(ZSoft::UInt32 index, const UcDbDataCell& cell);
    virtual Ucad::ErrorStatus removeCellAt(ZSoft::UInt32 index);
    virtual Ucad::ErrorStatus getIndexAtCell(const UcDbDataCell& cell, ZSoft::UInt32& index) const;

    virtual ZSoft::UInt32 numCells() const;

private:
    friend class UcDbSystemInternals;
    friend class UcDbImpDataColumn;
    UcDbImpDataColumn* mpImpDataColumn;
};

class UcDbDataTable : public UcDbObject
{
public:
    UCDB_DECLARE_MEMBERS(UcDbDataTable);
    
    UcDbDataTable();
    virtual ~UcDbDataTable(); 
   
    virtual UcDbDataTable& operator = (const UcDbDataTable& table);

    virtual ZSoft::UInt32 numColumns() const;
    virtual ZSoft::UInt32 numRows() const;

    virtual Ucad::ErrorStatus setNumRowsPhysicalSize(ZSoft::UInt32 n);
    virtual Ucad::ErrorStatus setNumRowsGrowSize(ZSoft::UInt32 n);
    virtual ZSoft::UInt32 numRowsPhysicalSize() const;
    virtual ZSoft::UInt32 numRowsGrowSize() const;
    virtual Ucad::ErrorStatus setNumColsPhysicalSize(ZSoft::UInt32 n);
    virtual Ucad::ErrorStatus setNumColsGrowSize(ZSoft::UInt32 n);
    virtual ZSoft::UInt32 numColsPhysicalSize() const;
    virtual ZSoft::UInt32 numColsGrowSize() const;

    virtual const ZTCHAR * tableName() const;
    virtual Ucad::ErrorStatus setTableName(const ZTCHAR * pName);

    virtual Ucad::ErrorStatus getColumnAt(ZSoft::UInt32 index,
        const UcDbDataColumn*& pCol) const;
    virtual Ucad::ErrorStatus getColumnNameAt(ZSoft::UInt32 index,
        ZTCHAR *& pName) const;
    virtual Ucad::ErrorStatus getColumnTypeAt(ZSoft::UInt32 index, 
        UcDbDataCell::CellType& type) const;
    virtual Ucad::ErrorStatus getColumnIndexAtName(
        const ZTCHAR * pName, ZSoft::UInt32& index) const;

    virtual Ucad::ErrorStatus appendColumn(
        UcDbDataCell::CellType type, const ZTCHAR * pColName = NULL);
    virtual Ucad::ErrorStatus insertColumnAt(ZSoft::UInt32 index, 
        UcDbDataCell::CellType type, const ZTCHAR * pColName = NULL);
    virtual Ucad::ErrorStatus removeColumnAt(ZSoft::UInt32 index);

    virtual Ucad::ErrorStatus getRowAt(ZSoft::UInt32 index, 
        UcDbDataCellArray& outRow) const;
    virtual Ucad::ErrorStatus setRowAt(ZSoft::UInt32 index,
        const UcDbDataCellArray& row, bool bValidate = true);
    virtual Ucad::ErrorStatus appendRow(
        const UcDbDataCellArray& row, bool bValidate = true);

    virtual Ucad::ErrorStatus insertRowAt(ZSoft::UInt32 index,
        const UcDbDataCellArray& row, bool bValidate = true);
    virtual Ucad::ErrorStatus removeRowAt(ZSoft::UInt32 index);

    virtual Ucad::ErrorStatus getCellAt(ZSoft::UInt32 row, ZSoft::UInt32 col,
        UcDbDataCell& outCell) const;
    virtual Ucad::ErrorStatus setCellAt(ZSoft::UInt32 row, ZSoft::UInt32 col,
        const UcDbDataCell& cell);

    virtual Ucad::ErrorStatus dwgInFields(UcDbDwgFiler* filer);
    virtual Ucad::ErrorStatus dwgOutFields(UcDbDwgFiler* filer) const;
    virtual Ucad::ErrorStatus dxfInFields(UcDbDxfFiler* filer);
    virtual Ucad::ErrorStatus dxfOutFields(UcDbDxfFiler* filer) const;

    virtual Ucad::ErrorStatus audit(UcDbAuditInfo* pAuditInfo);
};

#pragma pack (pop)
